/*******************************************************************************
  * 文件：RelayCtrl.h
  * 作者：djy
  * 版本：v1.0.0
  * 日期：2021-02-04
  * 说明：继电器控制相关，继电器不允许同时动作，需至少间隔210ms
*******************************************************************************/
#include "RelayCtrl.h"
#include "RelayPower.h"
#include "Hardware_IO.h"
#include "ComFun.h"

static RelayCtrl_ts sRelayCtrl;

// 预留继电器控制
void RelayCtrlReserve(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayReserve = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayReserve = bState;
}

// 背部风机1控制
void RelayCtrlBackFan1(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayBackFan1 = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayBackFan1 = bState;
}

// 背部风机2控制
void RelayCtrlBackFan2(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayBackFan2 = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayBackFan2 = bState;
}

// 蜡马达控制
void RelayCtrlMotor(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayMotor = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayMotor = bState;
}

// 冷却风扇A控制
void RelayCtrlCoolFan1(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayCoolFan1 = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayCoolFan1 = bState;
}

// 冷却风扇B控制
void RelayCtrlCoolFan2(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayCoolFan2 = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayCoolFan2 = bState;
}

// 蒸发盘外控制
void RelayCtrlSteamPanOut(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelaySteamPanOut = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelaySteamPanOut = bState;
}

// 蒸发盘内控制
void RelayCtrlSteamPanIn(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelaySteamPanIn = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelaySteamPanIn = bState;
}

// 上内加热管控制
void RelayCtrlUpInHeatTube(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayUpInHeatTube = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayUpInHeatTube = bState;
}

// 上外加热管控制
void RelayCtrlUpOutHeatTube(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayUpOutHeatTube = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayUpOutHeatTube = bState;
}

// 下加热控制
void RelayCtrlDownHeatTube(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayDownHeatTube = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayDownHeatTube = bState;
}

// 炉灯控制
void RelayCtrlLamp(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayLamp = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayLamp = bState;
}

// 背部加热控制
void RelayCtrlBackHeatTube(Bool bState)
{
	sRelayCtrl.uRelayStatus.sRelayStatus.bRelayBackHeatTube = bState;
	sRelayCtrl.uRelayStatusBak.sRelayStatus.bRelayBackHeatTube = bState;
}

// 获取预留继电器控制状态
Bool RelayGetReserveState(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayReserve;
}

// 获取背部风机1继电器控制状态
Bool RelayGetBackFan1State(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayBackFan1;
}

// 获取背部风机2继电器控制状态
Bool RelayGetBackFan2State(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayBackFan2;
}

// 获取蜡马达继电器控制状态
Bool RelayGetMotorState(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayMotor;
}

// 获取冷却风扇继电器控制状态
Bool RelayGetCoolFan1State(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayCoolFan1;
}

// 获取冷却风扇2继电器控制状态
Bool RelayGetCoolFan2State(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayCoolFan2;
}

// 获取蒸发盘外继电器控制状态
Bool RelayGetSteamPanOutState(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelaySteamPanOut;
}

// 获取蒸发盘内继电器控制状态
Bool RelayGetSteamPanInState(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelaySteamPanIn;
}

// 获取上内继电器控制状态
Bool RelayGetUpInHeatTubeState(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayUpInHeatTube;
}

// 获取上外继电器控制状态
Bool RelayGetUpOutHeatTubeState(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayUpOutHeatTube;
}

// 获取下加热继电器控制状态
Bool RelayGetDownHeatTubeState(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayDownHeatTube;
}

// 获取灯继电器控制状态
Bool RelayGetLampState(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayLamp;
}

// 获取背部加热继电器控制状态
Bool RelayGetBackHeatTubeState(void)
{
	return sRelayCtrl.uRelayStatus.sRelayStatus.bRelayBackHeatTube;
}

/*******************************************************************************
  * 函数名：RelayCtrlHook_210MS
  * 功  能：继电器控制210MS回调
  * 参  数：无
  * 返回值：无
  * 说  明：1.多个继电器动作时，需要间隔220ms；
  *		   2.在过零检测的上升沿中断中调用，上升沿中断每20ms中断一次；
*******************************************************************************/
void RelayCtrlHook_220MS(void)
{
	U8 u8Index = 0;
	
	// 遍历sRelayCtrl.uRelayStatus
	for(u8Index = 0; u8Index < U8_RELAY_NUMS; u8Index++)
	{
		// 判断继电器控制状态和备份的控制状态是否相等
		if(TST_BIT(sRelayCtrl.uRelayStatus.u16RelayStatus,u8Index) == TST_BIT(sRelayCtrl.uRelayStatusBak.u16RelayStatus,u8Index))
		{
			Bool bState = OFF;

			// 若控制状态和备份状态相同，则代表需要动作继电器，获取要动作的状态
			if(TST_BIT(sRelayCtrl.uRelayStatus.u16RelayStatus,u8Index))
			{
				bState = ON;
			}
			else
			{
				bState = OFF;
			}
			
			// 根据u8Index位置开关相应继电器
			switch(u8Index)
			{
			case 0:
				Hardware_ReserveCtrl(bState);
			break;
			case 1:
				Hardware_BackFan1Ctrl(bState);
			break;
			case 2:
				Hardware_BackFan2Ctrl(bState);
			break;
			case 3:
				Hardware_WaxMotorCtrl(bState);
			break;
			case 4:
				Hardware_CoolFanACtrl(bState);
			break;
			case 5:
				Hardware_CoolFanBCtrl(bState);
			break;
			case 6:
				Hardware_SteamPanOutCtrl(bState);
			break;
			case 7:
				Hardware_SteamPanInCtrl(bState);
			break;
			case 8:
				Hardware_UpInHeatCtrl(bState);
			break;
			case 9:
				Hardware_UpOutHeatCtrl(bState);
			break;
			case 10:
				Hardware_DownHeatCtrl(bState);
			break;
			case 11:
				Hardware_LampCtrl(bState);
			break;
			case 12:
				Hardware_BackHeatCtrl(bState);
			break;
			}			

			// 取反uRelayStatusBak中的第u8Index个Bit，下次轮询时不再动作
			NOT_BIT(sRelayCtrl.uRelayStatusBak.u16RelayStatus,u8Index);			

			// 提前退出，等待下个220ms动作下一个继电器
			return;
		}
	}
}

/*******************************************************************************
  * 函数名：RelayCtrl_Init
  * 功  能：继电器控制初始化
  * 参  数：无
  * 返回值：无
  * 说  明：1.开启继电器12V供电；2.开启210毫秒定时器轮询控制
*******************************************************************************/
void RelayCtrl_Init(void)
{
    // 开启继电器12V供电
    Relay12VolCtrl(ON);
}

